package com.spiro.gis.tiledownload;

import com.spiro.gis.tiledownload.common.HttpUtils;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Shaoping Huang
 * @Description:
 * @Date: 1/14/2018
 */
public class TileDownloader implements Runnable {

    private final String suffix;
    private final String urlPattern;
    private final String baseTargetDir;
    private final BlockingQueue<TileCoordinate> queue;
    private boolean endFlag = false;
    private long downloadCount = 0;

    public TileDownloader(String urlPattern, String baseTargetDir, String suffix, BlockingQueue<TileCoordinate> queue) throws IOException {
        this.suffix = suffix;
        if (urlPattern.endsWith("/")) {
            urlPattern = urlPattern.substring(0, urlPattern.length() - 1);
        }
        this.urlPattern = urlPattern;
        File baseTargetDirFile = new File(baseTargetDir);
        this.baseTargetDir = baseTargetDirFile.getCanonicalPath();
        this.queue = queue;
    }

    public void run() {

        try {
            while (true) {

                if (endFlag) {
                    if (this.queue.size() == 0) {
                        break;
                    }
                }

                // Get TileCoordinate
                TileCoordinate tc = queue.poll(5L, TimeUnit.SECONDS);
                if (tc == null) {
                    continue;
                }

                String imgUrl = HttpUtils.buildImgUrl(urlPattern, tc);
                String imgFilePath = getImgFilePath(tc);

//                System.out.println("download " + imgUrl + " -> " + imgFilePath);
                try {
                    HttpUtils.downloadImgToPath(imgUrl, imgFilePath);
                    downloadCount++;
                } catch (IOException e) {
                    System.out.println(tc.toString() + "\t" + e.getMessage());
                }
            }
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + ": interrupted.");
        }

        System.out.println(Thread.currentThread().getName() + ": stopped.");
    }

    private String getImgFilePath(TileCoordinate tc) {
        return this.baseTargetDir + File.separator + tc.getZ() + File.separator + tc.getX() + File.separator + tc.getY() + suffix;
    }

    public long getDownloadCount() {
        return downloadCount;
    }

    public String getUrlPattern() {
        return urlPattern;
    }

    public String getBaseTargetDir() {
        return baseTargetDir;
    }

    public void setEndFlag(boolean endFlag) {
        this.endFlag = endFlag;
    }
}
